package lib

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

// GinContext 是gin.Context的适配器，用于替换yee.Context
type GinContext struct {
	*gin.Context
}

// NewGinContext 创建一个新的GinContext
func NewGinContext(c *gin.Context) *GinContext {
	return &GinContext{
		Context: c,
	}
}

// Logger 返回日志记录器接口
func (c *GinContext) Logger() Logger {
	return &GinLogger{}
}

// Bind 绑定请求参数到结构体
func (c *GinContext) Bind(obj interface{}) error {
	return c.Context.ShouldBindJSON(obj)
}

// QueryParam 获取查询参数
func (c *GinContext) QueryParam(key string) string {
	return c.Context.Query(key)
}

// BindQuery 绑定查询参数到结构体
func (c *GinContext) BindQuery(obj interface{}) error {
	return c.Context.ShouldBindQuery(obj)
}

// Param 获取路径参数
func (c *GinContext) Param(key string) string {
	return c.Context.Param(key)
}

// GetHeader 获取请求头
func (c *GinContext) GetHeader(key string) string {
	return c.Context.GetHeader(key)
}

// JSON 返回JSON响应
func (c *GinContext) JSON(code int, obj interface{}) error {
	c.Context.JSON(code, obj)
	return nil
}

// String 返回字符串响应
func (c *GinContext) String(code int, format string, values ...interface{}) error {
	c.Context.String(code, format, values...)
	return nil
}

// Set 设置上下文值
func (c *GinContext) Set(key string, value interface{}) {
	c.Context.Set(key, value)
}

// Get 获取上下文值
func (c *GinContext) Get(key string) (interface{}, bool) {
	return c.Context.Get(key)
}

// GetString 获取字符串类型的上下文值
func (c *GinContext) GetString(key string) string {
	return c.Context.GetString(key)
}

// GetInt 获取整数类型的上下文值
func (c *GinContext) GetInt(key string) int {
	return c.Context.GetInt(key)
}

// GetUint64 获取uint64类型的上下文值
func (c *GinContext) GetUint64(key string) uint64 {
	if val, exists := c.Context.Get(key); exists {
		if u64, ok := val.(uint64); ok {
			return u64
		}
		if str, ok := val.(string); ok {
			if u64, err := strconv.ParseUint(str, 10, 64); err == nil {
				return u64
			}
		}
	}
	return 0
}

// Request 获取HTTP请求
func (c *GinContext) Request() *http.Request {
	return c.Context.Request
}

// Response 获取HTTP响应写入器
func (c *GinContext) Response() gin.ResponseWriter {
	return c.Context.Writer
}

// Context 获取Go context
func (c *GinContext) GoContext() context.Context {
	return c.Context.Request.Context()
}

// Logger 接口定义
type Logger interface {
	Error(msg string)
	Info(msg string)
	Warn(msg string)
	Debug(msg string)
}

// GinLogger gin日志记录器实现
type GinLogger struct{}

func (l *GinLogger) Error(msg string) {
	log.Printf("[ERROR] %s", msg)
}

func (l *GinLogger) Info(msg string) {
	log.Printf("[INFO] %s", msg)
}

func (l *GinLogger) Warn(msg string) {
	log.Printf("[WARN] %s", msg)
}

func (l *GinLogger) Debug(msg string) {
	log.Printf("[DEBUG] %s", msg)
}

// HandlerFunc gin处理函数类型
type HandlerFunc func(*GinContext) error

// WrapHandler 包装处理函数为gin.HandlerFunc
func WrapHandler(handler HandlerFunc) gin.HandlerFunc {
	return func(c *gin.Context) {
		gc := NewGinContext(c)
		if err := handler(gc); err != nil {
			gc.Logger().Error(fmt.Sprintf("Handler error: %v", err))
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 1,
				"msg":  "Internal server error",
				"data": nil,
			})
		}
	}
}

// MiddlewareFunc gin中间件函数类型
type MiddlewareFunc func(*GinContext) error

// WrapMiddleware 包装中间件函数为gin.HandlerFunc
func WrapMiddleware(middleware MiddlewareFunc) gin.HandlerFunc {
	return func(c *gin.Context) {
		gc := NewGinContext(c)
		if err := middleware(gc); err != nil {
			gc.Logger().Error(fmt.Sprintf("Middleware error: %v", err))
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 1,
				"msg":  err.Error(),
				"data": nil,
			})
			c.Abort()
			return
		}
		c.Next()
	}
}
